<template>
    <div class="layout-container">
        <div class="layout-container-left">
            <UseTable :tableData="tableData" multiple @change="change" />
        </div>

        <div class="layout-container-right">
            <div class="form-box">
                <el-form label-width="auto">
                    <el-form-item label="聚类数量">
                        <el-input v-model="paramsData.k" type="number" />
                    </el-form-item>

                    <el-form-item label="距离阈值">
                        <el-input v-model="paramsData.distanceThreshold" type="number" />
                    </el-form-item>

                    <el-form-item label="距离停止">
                        <el-switch v-model="paramsData.useThreshold" />
                    </el-form-item>

                    <el-form-item label="度量方法">
                        <el-input v-model="paramsData.distanceMetric" />
                    </el-form-item>

                    <el-form-item>
                        <div class="data-select">
                            <DmData @dataChange="dataChange" />
                            <Upload @uploadSuccess="uploadSuccess" />
                        </div>
                    </el-form-item>

                    <el-form-item>
                        <el-button type="primary" @click="handleCalculate">计算</el-button>
                    </el-form-item>
                </el-form>
            </div>

            <el-divider />

            <div class="info-box">
                <h5>算法说明</h5>
                <p>通过凝聚法（从单个点开始逐步合并）或分裂法（从整体开始逐步拆分）构建聚类树，支持多种距离度量（如欧氏距离、曼哈顿距离）。</p>

                <h5>使用范围</h5>
                <ul>
                    <li>探索数据的层次结构（如物种分类、文本主题聚类）；</li>
                    <li>无需预先指定簇数，可通过距离阈值确定聚类数量；</li>
                    <li>计算复杂度较高，适合中小规模数据。</li>
                </ul>
            </div>
        </div>

        <Result v-model="resultShow" :originalData="originalData" :result="resultData" />
    </div>
</template>

<script setup lang="ts">
import {onActivated, onMounted, ref} from "vue"
import {ElMessage}                   from "element-plus"
import Result                        from "./components/Result.vue"
import {getExcel}                    from "@/api/data"
import {hierarchical}                from "@/api/group"
import Upload                        from "@/components/Upload.vue"
import UseTable                      from "@/components/UseTable.vue"
import DmData                        from "@/components/DmData.vue"

function dataChange(data) {
    tableData.value = data
}

function uploadSuccess(res) {
    tableData.value = res.data
}

let originalData = ref({
    listColumn: [],
    listAll   : []
})

function change(listColumn, listAll) {
    originalData.value.listColumn = listColumn
    originalData.value.listAll    = listAll

    paramsData.value.data = []

    let maxLength = Math.max(...listColumn.map(item => item.value.length))

    paramsData.value.data = Array.from({length: maxLength}, (_, index) =>
        listColumn.map(item => item.value[index])
    )
}

let paramsData = ref({
        data             : [],
        k                : 3,
        distanceThreshold: 2.5,
        useThreshold     : false,
        distanceMetric   : "euclidean"
    }
)

let resultShow = ref(false)
let resultData = ref("")

// 计算
function handleCalculate() {
    if (paramsData.value.data.length === 0) {
        ElMessage.warning("请选择数据")
        return
    }

    if (!paramsData.value.k) {
        ElMessage.warning("请填写参数")
        return
    }

    if (!paramsData.value.distanceThreshold) {
        ElMessage.warning("请填写参数")
        return
    }

    if (!paramsData.value.distanceMetric) {
        ElMessage.warning("请填写参数")
        return
    }

    hierarchical(paramsData.value).then((res: any) => {
        resultData.value = res?.data
        resultShow.value = true
    })
}

let loading   = ref(true)
let tableData = ref([])

let getTableData = () => {
    loading.value = true

    getExcel("hierarchical").then(res => res.data).then(data => tableData.value = data)

    loading.value = false
}

/**
 * 初始化参数
 */
function initParam() {

}

// -----------------------------主程序start-----------------------------------------
onMounted(() => {
    initParam()
    getTableData()
})

onActivated(() => {
    initParam()
    getTableData()
})
// -----------------------------主程序end-----------------------------------------

</script>

<style scoped>

</style>

